<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Composition</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Java2D, Java, tutorial, composition, programming, GUI, multiplatform">
<meta name="description" content="In this part of the Java 2D tutorial, we work with image composition.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Composition</h1>


<p>
In this part of the Java 2D programming tutorial, we will define compositing operations.
</p>

<p>
Compositing is the combining of visual elements from separate sources into single images. 
They are used to create the illusion that all those elements are parts of the same scene. 
Compositing is widely used in film industry to create crowds, entire new worlds which 
would be expensive or impossible to create otherwise. (wikipedia.org) 
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<h2>Operations</h2>

<p>
There are several compositing operations. We will show some of them in 
the next code example. The <code>AlphaComposite</code> class 
implements basic alpha compositing rules for combining source and destination 
colors to achieve blending and transparency effects with graphics and images.
</p>

<p>
Say we want to draw two objects on a panel. The first object drawn is called 
a destination. The second one a source. The <code>AlphaComposite</code> 
class determines how these two are going to be blended together. If we have a 
AlphaComposite.SRC_OVER rule, the pixels of the source object will be drawn, 
where the two objects overlap. 
</p>

<div class="codehead">Compositing.java</div>
<pre class="code">
package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Compositing extends JPanel {

    int rules[] = {
        AlphaComposite.DST,
        AlphaComposite.DST_ATOP,
        AlphaComposite.DST_OUT,
        AlphaComposite.SRC,
        AlphaComposite.SRC_ATOP,
        AlphaComposite.SRC_OUT,
    };


    public void paint(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        for (int x=20, y=20, i=0; i &lt; rules.length; x+=60, i++) {

            AlphaComposite ac = AlphaComposite.getInstance(rules[i], 0.8f);

            BufferedImage buffImg = new BufferedImage(60, 60,
                                        BufferedImage.TYPE_INT_ARGB);
            Graphics2D gbi = buffImg.createGraphics();

            gbi.setPaint(Color.blue);
            gbi.fillRect(0, 0, 40, 40);
            gbi.setComposite(ac);

            gbi.setPaint(Color.green);
            gbi.fillRect(5, 5, 40, 40);  

            g2d.drawImage(buffImg, x, y, null);
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Composition");
        frame.add(new Compositing());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 120);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
</pre>

<p>
We draw two rectangles and combine them with six different compositing operations. 
</p>


<pre class="explanation">
int rules[] = {
    AlphaComposite.DST,
    AlphaComposite.DST_ATOP,
    AlphaComposite.DST_OUT,
    AlphaComposite.SRC,
    AlphaComposite.SRC_ATOP,
    AlphaComposite.SRC_OUT,
};
</pre>

<p>
Here we have six different compositing rules. Only two of these 
have practical significance. If not sure what 
compositing rule to use, pick up the SRC_OVER rule. 
</p>


<pre class="explanation">
AlphaComposite ac = AlphaComposite.getInstance(rules[i]);
</pre>

<p>
Here we get the <code>AlphaComposite</code> class. 
</p>

<pre class="explanation">
BufferedImage buffImg = new BufferedImage(60, 60, BufferedImage.TYPE_INT_ARGB);
Graphics2D gbi = buffImg.createGraphics();
</pre> 

<p>
We use a buffer image to perform the composition operations. 
</p>

<pre class="explanation">
gbi.setComposite(ac);
</pre> 

<p>
Sets the Composite for the Graphics2D context.
</p>


<pre class="explanation">
g2d.drawImage(buffImg, x, y, null);
</pre> 

<p>
We draw the image on the panel. 
</p>


<img src="/img/gfx/java2d/composition.png" alt="Composition">
<div class="figure">Figure: Composition</div>


<h2>Sun and Cloud</h2>

<p>
In the next example we show the Sun coming from behind a cloud. 
We will use composition technique in this animation.
</p>

<div class="codehead">SunAndCloud.java</div>
<pre class="code">
package com.zetcode;

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class SunAndCloud extends JPanel implements ActionListener {

    Image sun;
    Image cloud;
    Timer timer;
    private float alpha;

    public SunAndCloud() {
        sun = new ImageIcon(this.getClass().getResource("sun.png")).getImage();
        cloud = new ImageIcon(this.getClass().getResource("cloud.png")).getImage();
        timer = new Timer(800, this);
        timer.start();
        alpha = 1f;
    }

    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

        BufferedImage buffImg = new BufferedImage(220, 140,
                                    BufferedImage.TYPE_INT_ARGB);
        Graphics2D gbi = buffImg.createGraphics();

        AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);

        gbi.drawImage(sun, 40, 30, null);
        gbi.setComposite(ac);
        gbi.drawImage(cloud, 0, 0, null);

        g2d.drawImage(buffImg, 20, 20, null);
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("Sun &amp; Cloud");
        frame.add(new SunAndCloud());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 210);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    public void actionPerformed(ActionEvent e) {
        alpha -= 0.1;
        if (alpha &lt;= 0) {
            alpha = 0;
            timer.stop();
        }
        repaint();
    }
}
</pre>

<p>
The Sun comes from behind the cloud. The cloud finally disappears.  
</p>


<pre class="explanation">
sun = new ImageIcon(this.getClass().getResource("sun.png")).getImage();
cloud = new ImageIcon(this.getClass().getResource("cloud.png")).getImage();
</pre> 

<p>
We have two images, the Sun and the cloud. 
</p>

<pre class="explanation">
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
</pre> 

<p>
We use the <code>AlphaComposite.SRC_OVER</code> rule. Here the source 
blends with destination and overwrites empty pixels. 
</p>

<img src="/img/gfx/java2d/sunandcloud.png" alt="Sun &amp; Cloud">
<div class="figure">Figure: Sun &amp; Cloud</div>


<p>
In this part of the Java 2D tutorial, we have talked about image composition.
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified November 2, 2008  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

